"""
==============================================================
Square Root Estimation Algorithms (No Functions)
Topic       : Guess & Check, Approximation, Bisection Search
Objective   : Estimate √A using three different algorithms
==============================================================
"""

from math import sqrt

# -------------------------------
# Configuration
# -------------------------------
A   = 12345          # Known area (m²)
TOL = 1e-6           # Tolerance for accuracy

# --- Safety check ---
if A < 0:
    raise ValueError("A must be non-negative")

true_val = sqrt(A)   # Used only for verification

print("\n=== SQUARE ROOT LAB REPORT (No Functions) ===")
print(f"Given area A = {A}")
print(f"True √A      = {true_val:.6f}\n")


# ===============================================================
# 1) GUESS & CHECK METHOD
# ===============================================================
print(">>> 1) Guess & Check")

# TODO: Initialize guess, step, and count
# Example: guess = 0.0, step = 0.01, count = 0
# --------------------------------------------
TOL = 0.1
guess =105
step  = 0.0001
count = 0
while abs(guess**2-A)>= TOL:
    guess +=step
    count +=1
if abs(guess**2-A)>= TOL and guess*2 > A:
    print("fail")

else:
    print(guess,count)#confirming to be sure

# TODO: Repeat until guess² >= A
# Each iteration: increase guess by step, count += 1
# --------------------------------------------
# while ...:
#     ...
#     ...

# Compute error
error = abs(guess - true_val)

print(f"{'Guess & Check':20s} | Estimate: {guess:12.6f} | Error: {error:10.3e} | Iter: {count:7d}")


# ===============================================================
# 2) APPROXIMATION METHOD (Step Halving / Decimal Reduction)
# ===============================================================
print("\n>>> 2) Approximation Method")

# TODO: Initialize guess, step, and count
# Example: guess = 0.0, step = max(1.0, A / 10.0), count = 0
# --------------------------------------------
A = 12345
TOL = 0.1
guess = 55
step  = A/10
count = 0

while abs(guess**2-A) > TOL:
    if (guess + step)**2 <= A:
        guess += step
    else:
        step = step/10
    count +=1

# TODO: While |guess² - A| > TOL:
# If (guess + step)² ≤ A → move forward
# Else → divide step by 10
# --------------------------------------------
# while ...:
#     ...
#

error = abs(guess - 0)
print(f"{'Approximation':20s} | Estimate: {guess:12.6f} | Error: {error:10.3e} | Iter: {count:7d}")


# ===============================================================
# 3) BISECTION SEARCH METHOD
# ===============================================================
print("\n>>> 3) Bisection Search")

# TODO: Initialize low, high, mid, count
# Example: low = 0.0, high = max(1.0, float(A)), mid = (low + high)/2, count = 0
# --------------------------------------------
A = 12345
TOL = 0.01
guess =50
low   = 0
high  = max(1.0,float(A))
mid   = (low + high)/2
count = 0
#Two versions of the same code I will write. one utilizes mid variable more than the other.This first version is how we did it in class.
#while abs(guess**2-A) >= TOL:
#    if guess**2> guess:
#        high = guess
#    else:
#        low = guess
#    guess = (high + low)/2
#    count +=1
#if abs(guess**2-A) >= TOL:
#    print("fail")
#else:
#    print(guess)



##This one utilezes mid more and is as instructed by the reccomendations in this terminal
while abs(mid**2-A)>TOL:
    if mid**2 <A:
        low = mid
    else:
        high = mid
    mid = (low+high)/2
    count +=1

# TODO: While |mid² - A| > TOL:
# If mid² < A → low = mid
# Else → high = mid
# Update mid = (low + high)/2
# --------------------------------------------
# while ...:
#     ...
#     count += 1

error = abs(mid - true_val)
print(f"{'Bisection':20s} | Estimate: {mid:12.6f} | Error: {error:10.3e} | Iter: {count:7d}")

